package service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import www.truongnha.com.R;
import www.truongnha.com.TruongNhaLogin;
import Config.MyLog;
import Config.setting;
import TruongNhaLib.Attend;
import TruongNhaLib.DatabaseHandler;
import TruongNhaLib.JSONParser;
import TruongNhaLib.SubjectMark;
import TruongNhaLib.UserFunctions;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

//Service for: 1. update new mark 2.update absense
public class StudentService extends Service {
	private int nId = 0; // id for each notification
	private boolean binded = false;
	private boolean logged = false;
	private boolean dataLoaded = false;
	private ArrayList<Attend> arrayAttendOld = new ArrayList<Attend>();
	private ArrayList<Attend> arrayAttendCur = new ArrayList<Attend>();

	private ArrayList<SubjectMark> arraySubMarkOld = new ArrayList<SubjectMark>();
	private ArrayList<SubjectMark> arraySubMarkCur = new ArrayList<SubjectMark>();
	private static String host = setting.getHost();
	private static String url_student_mark_cur_term = host
			+ "api/markForAStudent/"; // + student_id
	private static String url_getAttendanceForStudent_allYear = host
			+ "api/getAttendanceForStudent/allYear";

	private HashMap<String, String> userDetail;
	private UserFunctions uf = new UserFunctions();
	// Key for user node:
	private static String KEY_SUCCESS = "success";

	@Override
	public void onCreate() {
		super.onCreate();
		Toast.makeText(getApplicationContext(), "service onCreate",
				Toast.LENGTH_SHORT).show();
		dataLoaded = false;
	}

	private final IBinder mBinder = new MyBinder();
	private ArrayList<String> list = new ArrayList<String>();

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		if (uf.isSavedSession(getApplicationContext())) {
			MyLog.show("cookie loaded from service");
		}
		Log.d("LocalWordService", "onstartCommand");
		list.add("Linux " + (list.size() + 1));
		// Check new mark
		// Check absense
		// Get data for main Class
		// Create db object:
		if (isNetworkAvailable(getApplicationContext())) {// Check net
			uf = new UserFunctions();
			if (uf.isRememberStudent(getApplicationContext())) {// Check
																// isStudent
				DatabaseHandler db = new DatabaseHandler(
						getApplicationContext());
				userDetail = db.getUserDetails();
				if (uf.isSavedSession(getApplicationContext())) {
					Toast.makeText(getApplicationContext(),
							"Loaded cookies from data", Toast.LENGTH_SHORT)
							.show();
					new getMarkTask().execute(url_student_mark_cur_term
							+ userDetail.get("user_id"));
				}
				/*
				 * //Check logged if(!logged){ Log.d("logging", "not log"); new
				 * loginTask().execute(url_login); } else{ Log.d("logging",
				 * "logged"); new
				 * getMarkTask().execute(url_student_mark_cur_term +
				 * userDetail.get("user_id")); }
				 */}
		}else{
			Toast.makeText(getApplicationContext(), "restart sv, but no network =))", Toast.LENGTH_SHORT).show();
		}
		return Service.START_NOT_STICKY;
	}

	@Override
	public void onDestroy() {
		// clear data when stop
		list.clear();
		logged = false;
		arraySubMarkCur.clear();
		arraySubMarkOld.clear();
		Toast.makeText(getApplicationContext(), "odestroy", Toast.LENGTH_SHORT)
				.show();
		super.onDestroy();
	}

	@Override
	public IBinder onBind(Intent arg0) {
		Toast.makeText(getApplicationContext(), "std service: onbind ->true",
				Toast.LENGTH_SHORT).show();
		Log.d("StudentService", "return mBinder");
		binded = true;
		return mBinder;
	}

	@Override
	public boolean onUnbind(Intent intent) {
		Toast.makeText(getApplicationContext(),
				"std service: onUnbind -> false", Toast.LENGTH_SHORT).show();
		binded = false;
		return super.onUnbind(intent);
	}

	public class MyBinder extends Binder {
		public StudentService getService() {
			return StudentService.this;
		}
	}

	public ArrayList<SubjectMark> getArraySubmark() {
		return arraySubMarkCur;
	}
	public ArrayList<Attend> getArrayAttend(){
		return arrayAttendCur;
	}

	public List<String> getWordList() {
		return list;
	}

	@SuppressWarnings("deprecation")
	public void createNotification(String title, String message, String notify) {
		NotificationManager notificationManager = (NotificationManager) getBaseContext()
				.getSystemService("notification");
		Notification myNotification;
		myNotification = new Notification(R.drawable.icon, notify,
				System.currentTimeMillis());
		Context context = getApplicationContext();
		String notificationTitle = title;
		String notificationText = message;
		Intent myIntent = new Intent(getApplicationContext(),
				TruongNhaLogin.class);
		PendingIntent pendingIntent = PendingIntent.getActivity(
				getBaseContext(), 0, myIntent,
				PendingIntent.FLAG_UPDATE_CURRENT);
		// myNotification.defaults |= Notification.DEFAULT_SOUND;
		myNotification.defaults |= Notification.DEFAULT_LIGHTS;
		myNotification.defaults |= Notification.DEFAULT_VIBRATE;
		myNotification.flags |= Notification.FLAG_AUTO_CANCEL;
		myNotification.setLatestEventInfo(context, notificationTitle,
				notificationText, pendingIntent);
		nId++;
		notificationManager.notify(nId, myNotification);
	}

	private void compareMark(ArrayList<SubjectMark> oldM,
			ArrayList<SubjectMark> newM) {
		Log.d("comparing", "oldsixe = " + oldM.size());
		// Compare
		if (oldM.size() != newM.size())
			return;
		int size = oldM.size();
		for (int i = 0; i < size; i++) {
			// Log.d("comparing", "oldsize i = "+i);
			if (oldM.get(i).getId() != newM.get(i).getId())
				continue;
			newM.get(i).copyStatus(oldM.get(i));// copy current unread status
			newM.get(i).compare(oldM.get(i));
		}
		// Send notification
		Log.d("notifying", "So mon hoc = " + size);
		for (int i = 0; i < size; i++) {
			List<String> result = newM.get(i).getNotifyString(oldM.get(i));
			int j = result.size();
			if (j > 0) {
				Log.d("notifying", "So diem moi cua 1 mon = " + j);
				String string = "";
				for (int k = 0; k < j; k++) {
					string = string + result.get(k) + " \n";
				}
				if (!binded)
					createNotification("Môn " + newM.get(i).getTitle(), string,
							"Thông báo điểm mới");
			}

		}
	}

	private void compareAttend(List<Attend> old, List<Attend> cur) {
		if (old.size() == 0) 
			return;
		if (old.size() >= cur.size())
			return;
		int status = cur.size() - old.size();
		String title = "Thông báo nghỉ học: " + status + " buổi";
		String message = "";
		for (int i = cur.size() - status; i < cur.size(); i++) {
			message = message + "Ngày " + cur.get(i).getTime() ;
			switch (cur.get(i).getType()) {
			case 3:
				message = message + " Nghỉ học không phép  \n";
				break;
			case 2:
				message = message + " Đi học muộn   \n";
				break;
			case 1:
				message = message + " Nghỉ học có phép  \n";
				break;
			default:
				break;
			}
		}
		createNotification(title, message, title);
		// for (int i = cur.size() - 1, j = old.size() - 1; i < 0; i--, j--) {
		// if (status == 0 || i < 0 || j < 0)
		// break;
		// Log.d("i=" + i, "j=" + j);
		// if (!cur.get(i).getTime().equals(old.get(j).getTime())) {
		// message = message + cur.get(i).getTime() + " \n";
		// j++;
		// status--;
		// }
		// }
	}

	public boolean isNetworkAvailable(Context context) {
		ConnectivityManager connectivity = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		if (connectivity == null) {
		} else {
			NetworkInfo[] info = connectivity.getAllNetworkInfo();
			if (info != null) {
				for (int i = 0; i < info.length; i++) {
					if (info[i].getState() == NetworkInfo.State.CONNECTED)
						return true;
				}
			}
		}
		return false;
	}

	class getMarkTask extends AsyncTask<String, Void, Void> {
		private String message;
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			message = "";
			Toast.makeText(getApplicationContext(), "getting mark",
					Toast.LENGTH_SHORT).show();
		}

		@Override
		protected Void doInBackground(String... params) {
			JSONArray mark_array = new JSONParser().getJSONArray(params[0]);
			int size = mark_array.length();
			if (size == 1) {// May be receive error message or one student.
				try {
					message = mark_array.getString(0);
					Log.d("mess", message);
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
			if(!message.equals("")) return null;//error
			arraySubMarkOld.clear();
			arraySubMarkOld = new ArrayList<SubjectMark>(arraySubMarkCur);
			arraySubMarkCur.clear();
			// Log.d("comparing", "-1");
			try {
				// Log.d("comparing", "Ex = " +size);
				// add new
				for (int i = 0; i < size; i++) {
					// Log.d("comparing", "x"+i);
					SubjectMark sm = new SubjectMark(
							mark_array.getJSONObject(i));
					arraySubMarkCur.add(sm);
				}
				// Log.d("size = ", arraySubMark.size() +" " );
			} catch (JSONException e) {
				// Log.d("comparing", "y");
				e.printStackTrace();
			}
			// Log.d("comparing", "0");
			compareMark(arraySubMarkOld, arraySubMarkCur);
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			if(!message.equals("")){//error
				Toast.makeText(getApplicationContext(), "async attent: "+ message, Toast.LENGTH_SHORT).show();
				return;
			}
			// Broadcast to studentFragment when done loading
			Intent doneLoading = new Intent();
			doneLoading.setAction("DONE_REFRESH_MARK");
			doneLoading.putExtra("doneLoading", true);
			getApplicationContext().sendBroadcast(doneLoading);
			new getAttendanceTask()
					.execute(url_getAttendanceForStudent_allYear);
			dataLoaded = true;
		}
	}// End class getTimeTask
		// LoginAsyncTask

	class loginTask extends AsyncTask<String, Void, Void> {
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}

		@Override
		protected Void doInBackground(String... params) {
			JSONObject json;
			json = uf.loginUser(getApplicationContext());
			// check for login response
			try {
				Log.d("LOG", "Post 06");
				if (json.getString(KEY_SUCCESS) != null) {
					logged = true;
					Log.d("logging", "=true");
				}
			} catch (JSONException e) {
				Log.d("LOG", "Post 12");
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			new getMarkTask().execute(url_student_mark_cur_term
					+ userDetail.get("user_id"));
		}
	}// end LoginAsyncTask

	/**
	 * 
	 * @author thanhnx get attendance data
	 */
	class getAttendanceTask extends AsyncTask<String, Void, Void> {
		private String message;
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			message = "";
			Intent doneLoading = new Intent();
			doneLoading.setAction("DONE_LOADING_ACTION");
			doneLoading.putExtra("doneLoading", false);
			getApplicationContext().sendBroadcast(doneLoading);
		}

		@Override
		protected Void doInBackground(String... params) {
			JSONArray attend_array = new JSONParser().getJSONArray(params[0]);
			int size = attend_array.length();
			if (size == 1) {// May be receive error message or one student.
				try {
					message = attend_array.getString(0);
					Log.d("mess", message);
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
			if(!message.equals("")) return null;
			arrayAttendOld.clear();
			arrayAttendOld = new ArrayList<Attend>(arrayAttendCur);
			arrayAttendCur.clear();
			try {
				for (int i = 0; i < size; i++) {
					Attend attend = new Attend(attend_array.getJSONObject(i));
					arrayAttendCur.add(attend);
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}
			compareAttend(arrayAttendOld, arrayAttendCur);
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			// Broadcast to main activity when done loading
			Intent doneLoading = new Intent();
			doneLoading.setAction("DONE_LOADING_ACTION");
			doneLoading.putExtra("doneLoading", true);
			getApplicationContext().sendBroadcast(doneLoading);
			if(!message.equals("")){//no error.
				Toast.makeText(getApplicationContext(), "async attent: "+ message, Toast.LENGTH_SHORT).show();
				return;
			}
		}
	}// End class getTermTask

	public boolean dataLoaded() {
		return dataLoaded;
	}
}